﻿#include "updateprogrems.h"
#include <QApplication>
#include <QFile>
#include <QDir>
#include <QDebug>
#include "../commons/configfile.h"

#include "../seriels/protocolconvert.h"
#include "../seriels/mixdevice.h"

#ifdef win32
#include <QuaZip.h>
#include <QuaZipDir.h>
#endif

#include <QFile>
#include <QDebug>



UpdateProgrems  * UpdateProgrems::m_updateProgrems = NULL;
UpdateProgrems::UpdateProgrems(QObject *parent) : QObject(parent),
    ymodemFileTransmit(new YmodemFileTransmit),
    ymodemFileReceive(new YmodemFileReceive)
  , m_mcuUpdateTimer0(NULL)
  , m_mcuUpdateTimer1(NULL)
  // , m_cmdProcess(NULL)
{
    //m_cmdProcess = new QProcess(this);
    // connect(m_cmdProcess,SIGNAL(),this,SLOT() );
    m_mcuUpdateTimer0 = new QTimer(this);
    connect(m_mcuUpdateTimer0,SIGNAL( timeout() ),this,SLOT( onMcuUpdateTimeout0() ) );
    m_mcuUpdateTimer1 = new QTimer(this);
    connect(m_mcuUpdateTimer1,SIGNAL(timeout()  ),this,SLOT( onMcuUpdateTimeout1() ) );
    transmitButtonStatus = false;
    receiveButtonStatus  = false;
    connect(ymodemFileTransmit, SIGNAL(transmitProgress(int)), this, SLOT(onTransmitProgress(int)));
    connect(ymodemFileReceive, SIGNAL(receiveProgress(int)), this, SLOT(onReceiveProgress(int)));
    connect(ymodemFileTransmit, SIGNAL(transmitStatus(YmodemFileTransmit::Status)), this, SLOT(onTransmitStatus(YmodemFileTransmit::Status)));
    connect(ymodemFileReceive, SIGNAL(receiveStatus(YmodemFileReceive::Status)), this, SLOT(onReceiveStatus(YmodemFileReceive::Status)));

    initUpdates();
}

UpdateProgrems::~UpdateProgrems()
{

}
bool  UpdateProgrems::checkZipIntegrity(const QString &zipPath) {
    #ifdef win32
    QuaZip zip(zipPath);
    if (!zip.open(QuaZip::mdUnzip)) {

        return false;
    }

    QuaZipDir dir(&zip);
    if (!dir.exists()) {

        return false;
    }


#endif
    return true;
}
void UpdateProgrems::initUpdates()
{
    QString docParhFile =  QApplication::applicationDirPath();
    QString docParhs = docParhFile;
    m_updateSourcePahts = docParhs;
    docParhFile +="/updatefiles";
    docParhs +="/shellfiles";
    m_updateShellPahts = docParhs;
    m_updatePahtsfiles = docParhFile;
    m_updatefiles = docParhFile+"/updates.zip";
    QDir dir(docParhFile);
    if(!dir.exists())
    {
        dir.mkdir(docParhFile);
#ifdef DEBUG_INFOR
        qDebug()<<__func__<<__LINE__;
#endif
    }
    else
    {
        clearDirectory(docParhFile);
#ifdef DEBUG_INFOR
        qDebug()<<__func__<<__LINE__;
#endif
    }
    QDir dira(docParhs);
    if(!dira.exists())
    {
        dira.mkdir(docParhs);
#ifdef DEBUG_INFOR
        qDebug()<<__func__<<__LINE__;
#endif
    }
    else
    {
        // clearDirectory(docParhs);
#ifdef DEBUG_INFOR
        qDebug()<<__func__<<__LINE__;
#endif
    }
}

UpdateProgrems *UpdateProgrems::gestance()
{
    if(m_updateProgrems == NULL){
        m_updateProgrems = new UpdateProgrems();
    }

    return m_updateProgrems;
}

void UpdateProgrems::saveFile(QByteArray infors)
{
    QFile file(m_updatefiles);
    if (!file.open(QIODevice::Append | QIODevice::Text)) {
        // 处理打开文件失败的情况
        return;
    }

    QTextStream stream(&file);
    stream << infors << endl;
}

void UpdateProgrems::transmitFile(QString paths)
{
#ifdef DEBUG_INFOR
    qDebug()<< metaObject()->className()<<__func__<<__LINE__<<"paths=="<<paths;

#endif
    if(transmitButtonStatus == false)
    {
        ProtocolConvert::gestance()->closeComSeriel();
        QString names =  ConfigFile::gestance()->getCom1Name();
        ymodemFileTransmit->setFileName(paths);
        ymodemFileTransmit->setPortName(names);
        ymodemFileTransmit->setPortBaudRate(QSerialPort::Baud115200);
#ifdef DEBUG_INFOR
        qDebug()<< metaObject()->className()<<__func__<<__LINE__;

#endif
        if(ymodemFileTransmit->startTransmit() == true)
        {
            transmitButtonStatus = true;

#ifdef DEBUG_INFOR
            qDebug()<< metaObject()->className()<<__func__<<__LINE__;

#endif
        }
        else
        {
#ifdef DEBUG_INFOR
            qDebug()<< metaObject()->className()<<__func__<<__LINE__;
#endif
        }
    }
    else
    {
#ifdef DEBUG_INFOR
        qDebug()<< metaObject()->className()<<__func__<<__LINE__;

#endif
        ymodemFileTransmit->stopTransmit();
    }
}

void UpdateProgrems::receiveFile(QString paths)
{
#ifdef DEBUG_INFOR
    qDebug()<< metaObject()->className()<<__func__<<__LINE__<<"paths=="<<paths;

#endif
    if(receiveButtonStatus == false)
    {
        ProtocolConvert::gestance()->closeComSeriel();
        QString names =  ConfigFile::gestance()->getCom1Name();
#ifdef DEBUG_INFOR
        qDebug()<< metaObject()->className()<<__func__<<__LINE__<<"names=="<<names;

#endif
        ymodemFileReceive->setFilePath(paths);
        ymodemFileReceive->setPortName(names);
        ymodemFileReceive->setPortBaudRate(QSerialPort::Baud115200);
#ifdef DEBUG_INFOR
        qDebug()<< metaObject()->className()<<__func__<<__LINE__;

#endif
        if(ymodemFileReceive->startReceive() == true)
        {
            receiveButtonStatus = true;
#ifdef DEBUG_INFOR
            qDebug()<< metaObject()->className()<<__func__<<__LINE__;

#endif

        }
        else
        {
#ifdef DEBUG_INFOR
            qDebug()<< metaObject()->className()<<__func__<<__LINE__;
#endif
        }
    }
    else
    {
#ifdef DEBUG_INFOR
        qDebug()<< metaObject()->className()<<__func__<<__LINE__;

#endif
        ymodemFileReceive->stopReceive();
    }
}

void UpdateProgrems::receivePaths()
{
    receiveFile( m_updatePahtsfiles );
}

void UpdateProgrems::writeFlile(QString infos)
{

    QString filea = m_updateSourcePahts+"/tag.txt";
    QFile file(filea);
    if(file.open(QIODevice::WriteOnly)){
        file.write(infos.toUtf8());
        file.flush();
        file.close();
    }
}

void UpdateProgrems::onTransmitProgress(int progress)
{
#ifdef DEBUG_INFOR
    qDebug()<< metaObject()->className()<<__func__<<__LINE__<<"progress=="<<progress;
#endif
}

void UpdateProgrems::onReceiveProgress(int progress)
{
#ifdef DEBUG_INFOR
    qDebug()<< metaObject()->className()<<__func__<<__LINE__<<"progress=="<<progress;
#endif
}

void UpdateProgrems::onTransmitStatus(Ymodem::Status status)
{
#ifdef DEBUG_INFOR
    qDebug()<< metaObject()->className()<<__func__<<__LINE__<<"status=="<<status;
#endif
    switch(status)
    {
    case YmodemFileTransmit::StatusEstablish:
    {
        break;
    }

    case YmodemFileTransmit::StatusTransmit:
    {
        break;
    }

    case YmodemFileTransmit::StatusFinish:
    {
        //   ymodemFileTransmit->stopTransmit();
        transmitButtonStatus = false;
        ProtocolConvert::gestance()->openComSeriel();
#ifdef DEBUG_INFOR
        qDebug()<< metaObject()->className()<<__func__<<__LINE__<<"status=="<<status;
#endif

        break;
    }

    case YmodemFileTransmit::StatusAbort:
    {
        //  ymodemFileTransmit->stopTransmit();
        transmitButtonStatus = false;
        ProtocolConvert::gestance()->openComSeriel();
#ifdef DEBUG_INFOR
        qDebug()<< metaObject()->className()<<__func__<<__LINE__<<"status=="<<status;
#endif

        break;
    }

    case YmodemFileTransmit::StatusTimeout:
    {
        //   ymodemFileTransmit->stopTransmit();
        transmitButtonStatus = false;
        ProtocolConvert::gestance()->openComSeriel();

#ifdef DEBUG_INFOR
        qDebug()<< metaObject()->className()<<__func__<<__LINE__<<"status=="<<status;
#endif

        break;
    }

    default:
    {
        // ymodemFileTransmit->stopTransmit();
        transmitButtonStatus = false;
        ProtocolConvert::gestance()->openComSeriel();
#ifdef DEBUG_INFOR
        qDebug()<< metaObject()->className()<<__func__<<__LINE__<<"status=="<<status;
#endif

    }
    }
}

void UpdateProgrems::onReceiveStatus(Ymodem::Status status)
{
#ifdef DEBUG_INFOR
    qDebug()<< metaObject()->className()<<__func__<<__LINE__<<"status=="<<status;
#endif
    switch(status)
    {
    case YmodemFileReceive::StatusEstablish:
    {
        break;
    }

    case YmodemFileReceive::StatusTransmit:
    {
        break;
    }

    case YmodemFileReceive::StatusFinish:
    {
        //ymodemFileReceive->stopReceive();
        //ymodemFileReceive->stopReceive();
//        QString pathsb = m_updateSourcePahts;

//        pathsb +="/";
//        QString pathsc = ymodemFileReceive->getFilePathName();
//        pathsc.replace("\r","");
//        pathsc.replace("\n","");

//        pathsb.replace("\r","");
//        pathsb.replace("\n","");
//        QString pathsd= pathsb+pathsc;
//#ifdef DEBUG_INFOR
//        qDebug()<< metaObject()->className()<<__func__<<__LINE__<<"pathsd=="<<pathsd;
//#endif
//        if(!checkZipIntegrity(pathsd) ){

//            QFile::remove(pathsd);
//            receiveButtonStatus = false;
//            ProtocolConvert::gestance()->openComSeriel();
//            return;
//        }
        receiveButtonStatus = false;
        ProtocolConvert::gestance()->openComSeriel();
#ifdef DEBUG_INFOR
        qDebug()<< metaObject()->className()<<__func__<<__LINE__<<"status=="<<status;
#endif
        MixDevice::gestance()->openLanes(16,1);
        if(m_mcuUpdateTimer0 != NULL){
            m_mcuUpdateTimer0->start(800);

        }
        break;
    }

    case YmodemFileReceive::StatusAbort:
    {
        //  ymodemFileReceive->stopReceive();
        receiveButtonStatus = false;
        ProtocolConvert::gestance()->openComSeriel();
#ifdef DEBUG_INFOR
        qDebug()<< metaObject()->className()<<__func__<<__LINE__<<"status=="<<status;
#endif
        break;
    }

    case YmodemFileReceive::StatusTimeout:
    {
        // ymodemFileReceive->stopReceive();
        receiveButtonStatus = false;
        ProtocolConvert::gestance()->openComSeriel();
#ifdef DEBUG_INFOR
        qDebug()<< metaObject()->className()<<__func__<<__LINE__<<"status=="<<status;
#endif
        break;
    }

    default:
    {
        // ymodemFileReceive->stopReceive();
        receiveButtonStatus = false;
        ProtocolConvert::gestance()->openComSeriel();
#ifdef DEBUG_INFOR
        qDebug()<< metaObject()->className()<<__func__<<__LINE__<<"status=="<<status;
#endif
    }
    }
}

void UpdateProgrems::onMcuUpdateTimeout0()
{
    if(m_mcuUpdateTimer0 != NULL){
        m_mcuUpdateTimer0->stop();
    }
    MixDevice::gestance()->openLanes(12,4);
    if(m_mcuUpdateTimer1 != NULL){
        m_mcuUpdateTimer1->start(800);

    }
}

void UpdateProgrems::onMcuUpdateTimeout1()
{
    if(m_mcuUpdateTimer1 != NULL){
        m_mcuUpdateTimer1->stop();
    }


    QString pathsa = m_updateSourcePahts;
    QString pathsb = m_updateSourcePahts;
    pathsa+="/../filezips/fileunzips";
    pathsb +="/";
    QString pathsc = ymodemFileReceive->getFilePathName();
    pathsc.replace("\r","");
    pathsc.replace("\n","");

    pathsb.replace("\r","");
    pathsb.replace("\n","");

    /*
    if(pathsc.contains(".bin",Qt::CaseInsensitive)){
        QString pathsd =pathsc;
        pathsd.replace(".bin",".zip",Qt::CaseInsensitive);
        QFile file(pathsc);

        // 尝试重命名文件
        if (file.rename(pathsd)) {
#ifdef DEBUG_INFOR
            qDebug()<< metaObject()->className()<<__func__<<__LINE__<< "文件重命名成功!";

#endif
            qDebug() << "文件重命名成功!";
        } else {
#ifdef DEBUG_INFOR
            qDebug()<< metaObject()->className()<<__func__<<__LINE__<< "文件重命名失败:" << file.errorString();

#endif

        }
        pathsc  =pathsd;
    }
    */
    QStringList blista;
    pathsb.replace("\\","\/");
    pathsc.replace("\\","\/");


    blista<<pathsb<<pathsc;
#ifdef DEBUG_INFOR
    qDebug()<< metaObject()->className()<<__func__<<__LINE__<<"pathsa=="<<pathsa;
    qDebug()<< metaObject()->className()<<__func__<<__LINE__<<"blista=="<<blista;
#endif
    // return;

#ifdef win32
    writeFlile("1");
#endif
    QProcess::startDetached(pathsa,blista);

    qApp->exit(0);
#ifdef DEBUG_INFOR
    //    QProcess processa;
    //    processa.start(pathsa,blista);
    //    processa.waitForFinished();
    //    qDebug()<< metaObject()->className()<<__func__<<__LINE__<<"processa=="<<processa.readAll();
#endif
}

void UpdateProgrems::clearDirectory(const QString &path) {
    QDir dir(path);

    // 获取目录下所有文件和子目录
    const auto entries = dir.entryInfoList(QDir::AllEntries | QDir::NoDotAndDotDot);

    for (const auto &entry : entries) {
        if (entry.isFile()) {
            // 删除文件
#ifdef DEBUG_INFOR
            qDebug()<< metaObject()->className()<<__func__<<__LINE__;
#endif
            QFile::remove(entry.filePath());
        } else if (entry.isDir()) {
            // 递归删除子目录
#ifdef DEBUG_INFOR
            qDebug()<< metaObject()->className()<<__func__<<__LINE__;
#endif
        }
    }
}
